package com.cloud.quickcore.admin.service;

import com.cloud.quickcommon.biz.BaseBizService;
import com.cloud.quickcommon.exception.BusinessException;
import com.cloud.quickcommon.utils.RoleUtile;
import com.cloud.quickcore.admin.dao.SysRoleRepository;
import com.cloud.quickcore.admin.dao.SysUserRepository;
import com.cloud.quickcore.admin.dao.SysUserRoleRepository;
import com.cloud.quickcore.admin.dto.LoginDto;
import com.cloud.quickcore.admin.dto.UserRegisterDto;
import com.cloud.quickcore.admin.entity.SysRole;
import com.cloud.quickcore.admin.entity.SysUser;
import com.cloud.quickcore.admin.entity.SysUserRole;
import com.cloud.quickcore.admin.enums.FrozenTypenEnum;
import com.cloud.quickcore.admin.vo.AdminLoginVo;
import com.cloud.quickcore.shiro.SimpleHashFactory;
import com.cloud.quickcore.shiro.jwt.JWTUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Example;
import org.springframework.stereotype.Service;

import javax.persistence.Transient;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 用户注册、登陆 --Service
 *
 * @author NiJo_H
 * @version 1.0
 * @date 2019/7/30 21:43
 */
@Service
@CacheConfig(cacheNames = "SysUser")
public class SysUserService implements BaseBizService<UserRegisterDto, SysUser, String> {

    @Autowired
    private SimpleHashFactory simpleHashFactory;

    @Autowired
    private SysUserRepository userRepository;

    @Autowired
    private SysUserRoleRepository userRoleRepository;

    @Autowired
    private SysRoleRepository roleRepository;

    @Autowired
    private SysPermissionService permissionService;


    @Override
    public SysUser save(UserRegisterDto dto) {
        /**dto转换对象*/
        SysUser sysUser = dto.convertEntity();
        /**生成盐*/
        String salt = simpleHashFactory.SimpleHashSalt();
        sysUser.setSalt(salt);
        /**加密明文*/
        sysUser.setPassword(simpleHashFactory.SimpleHashPwd(salt, sysUser.getPassword()));
        /**默认开通普通用户*/
        SysRole sysRole = roleRepository.findSysRoleByRoleCode(RoleUtile.NORMAL_CODE).orElseThrow(() ->
                new BusinessException("未查询到相关角色信息")
        );
        /**保存用户表*/
        userRepository.save(sysUser);
        /**构建用户--角色中间表*/
        SysUserRole userRole = new SysUserRole();
        userRole.setRoleId(sysRole.getId());
        userRole.setUserId(sysUser.getId());
        /**保存中间表*/
        userRoleRepository.save(userRole);
        return sysUser;
    }

    @Override
    public SysUser update(UserRegisterDto obj) {
        return null;
    }

    @Override
    @Transient
    public void romve(String id) {
        /**逻辑删除*/
        SysUser sysUser = userRepository.findById(id).orElseThrow(() -> new BusinessException("未查询到该用户"));
        sysUser.setDelete(true);
        userRepository.save(sysUser);
    }

    @Override
    public Optional<SysUser> findById(String s) {
        return Optional.empty();
    }

    @Override
    public List<SysUser> findAll() {
        return null;
    }


    /**
     * 登陆操作
     */
    @Cacheable(key = "#dto.getUserName()")
    public AdminLoginVo login(LoginDto dto) {
        /**查询用户*/
        SysUser sysUser = userRepository.findSysUserByUsername(dto.getUserName()).orElseThrow(() -> new BusinessException("用户名不存在!"));

        if (!simpleHashFactory.SimpleHashPwd(sysUser.getSalt(), dto.getPassword()).equals(sysUser.getPassword())) {
            throw new BusinessException("用户名密码错误!");
        }
        if (sysUser.getFrozen().getCode().equals(FrozenTypenEnum.FROZENED.getCode())) {
            throw new BusinessException("该账户已被冻结,请联系管理员");
        }
        /**封装返回信息*/
        AdminLoginVo vo = new AdminLoginVo();
        vo.setUsername(sysUser.getUsername());
        vo.setName(sysUser.getName());
        /**获取角色列表*/
        Set<SysRole> roles = sysUser.getRoles();
        vo.setRoles(roles.stream().map(SysRole::getName).collect(Collectors.toList()));
        /**获取菜单列表*/
        vo.setMenus(permissionService.findMenuTreeByRoles(roles));
        /**Token*/
        vo.setToken(JWTUtil.sign(sysUser.getUsername(), sysUser.getPassword()));
        return vo;
    }

    /**
     * 查询当前登陆用户菜单、权限、角色信息
     */
    @Cacheable(key = "#userId")
    public AdminLoginVo findUserPermissions(String userId) {
//        if(StringUtils.isEmpty(userId)){
//            List<SysUserVo> query = jdbcOperations.query("SELECT u.id,u.name,u.create_at,u.frozen,u.active,r.name as role_name FROM sys_user u,sys_user_role ur,sys_role r WHERE u.is_delete=false and u.id=ur.user_id and r.id=ur.role_id", new BeanPropertyRowMapper(SysUserVo.class));
//            return query;
//        }
        AdminLoginVo vo = new AdminLoginVo();
        SysUser sysUser = userRepository.findById(userId).orElseThrow(() -> new BusinessException("用户名不存在!"));
        vo.setName(sysUser.getName());
        vo.setUsername(sysUser.getUsername());
        vo.setRoles(sysUser.getRoles().stream().map(SysRole::getName).collect(Collectors.toList()));
        vo.setMenus(permissionService.findMenuTreeByRoles(sysUser.getRoles()));
        return vo;

    }

    /**
     * 更改用户角色
     */
    public void updateSysUserRole(String id, String roleCode) {
        SysRole sysRole = roleRepository.findSysRoleByRoleCode(roleCode).orElseThrow(() -> new BusinessException("未查询到角色信息"));
        List<Long> roleIdList = userRoleRepository.findRoleIdList(id);
        if (roleIdList.size() > 0) {
            roleIdList.forEach(x -> {
                SysUserRole userRole = userRoleRepository.findById(x).get();
                userRole.setRoleId(sysRole.getId());
                userRoleRepository.save(userRole);
            });
        }
    }

    /**
     * 通过userName查询用户信息
     *
     * @param userName 用户名
     * @return SysUser 用户信息对象
     */
    public SysUser findSysUserByUsername(String userName) {
        SysUser sysUser = new SysUser();
        sysUser.setUsername(userName);
        Optional<SysUser> opt = userRepository.findOne(Example.of(sysUser));
        return opt.isPresent() ? opt.get() : null;
    }

    /**
     * 添加后台超级管理员
     *
     * @param sysUser 提交对象
     * @return 返回成功对象
     */
    public SysUser saveSuperAdmin(SysUser sysUser) {
        /**生成盐*/
        String salt = simpleHashFactory.SimpleHashSalt();
        sysUser.setSalt(salt);
        /**加密明文*/
        sysUser.setPassword(simpleHashFactory.SimpleHashPwd(salt, sysUser.getPassword()));
        SysRole sysRole = roleRepository.findSysRoleByRoleCode(RoleUtile.SUPER_ADMIN_CODE).orElseThrow(() ->
                new BusinessException("未查询到相关角色信息")
        );
        /**保存用户表*/
        userRepository.save(sysUser);
        /**构建用户--角色中间表*/
        SysUserRole userRole = new SysUserRole();
        userRole.setRoleId(sysRole.getId());
        userRole.setUserId(sysUser.getId());
        /**保存中间表*/
        userRoleRepository.save(userRole);
        return sysUser;
    }
}
